package com.easy.framework.security.utils;

import org.springframework.security.oauth2.core.OAuth2AuthorizationException;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;

import jakarta.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * OAuth2 端点工具类
 */
public final class OAuth2EndpointUtils {
	public static final String ACCESS_TOKEN_REQUEST_ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc6749#section-5.2";
	private OAuth2EndpointUtils() {
	}

	/**
	 * 从请求中获取参数（兼容GET和POST）
	 */
	public static MultiValueMap<String, String> getParameters(HttpServletRequest request) {
		Map<String, String[]> parameterMap = request.getParameterMap();
		MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>(parameterMap.size());
		parameterMap.forEach((key, values) -> {
			if (values.length > 0) {
				for (String value : values) {
					parameters.add(key, value);
				}
			}
		});
		return parameters;
	}

	/**
	 * 验证授权请求参数
	 */
	public static void validateAuthorizationRequest(HttpServletRequest request) {
		// 验证必须参数
		String[] requiredParameters = {OAuth2ParameterNames.RESPONSE_TYPE, OAuth2ParameterNames.CLIENT_ID};
		for (String requiredParameter : requiredParameters) {
			if (!StringUtils.hasText(request.getParameter(requiredParameter))) {
				throwError(OAuth2ParameterNames.ERROR, "invalid_request", null);
			}
		}

		// 验证response_type
		String responseType = request.getParameter(OAuth2ParameterNames.RESPONSE_TYPE);
		if (!"code".equals(responseType)) {
			throwError(OAuth2ParameterNames.ERROR, "unsupported_response_type", null);
		}
	}

	/**
	 * 验证令牌请求参数
	 */
	public static void validateTokenRequest(HttpServletRequest request) {
		// 验证grant_type
		String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE);
		if (!StringUtils.hasText(grantType)) {
			throwError(OAuth2ParameterNames.ERROR, "invalid_request", "Missing grant_type parameter");
		}
	}

	/**
	 * 抛出OAuth2错误
	 */
	public static void throwError(String errorCode, String errorDescription, String errorUri) {
		throwError(errorCode, errorDescription, errorUri, null);
	}

	/**
	 * 抛出OAuth2错误（带额外参数）
	 */
	public static void throwError(String errorCode, String errorDescription, String errorUri, Map<String, Object> additionalParameters) {
		Map<String, Object> parameters = new HashMap<>();
		parameters.put(OAuth2ParameterNames.ERROR, errorCode);
		if (StringUtils.hasText(errorDescription)) {
			parameters.put(OAuth2ParameterNames.ERROR_DESCRIPTION, errorDescription);
		}
		if (StringUtils.hasText(errorUri)) {
			parameters.put(OAuth2ParameterNames.ERROR_URI, errorUri);
		}
		if (additionalParameters != null) {
			parameters.putAll(additionalParameters);
		}
		throw new OAuth2AuthorizationException(
				new OAuth2Error(errorCode, errorDescription, errorUri),
				parameters.toString());
	}

	/**
	 * 格式化OAuth2错误响应
	 */
	public static Map<String, Object> formatErrorResponse(OAuth2Error error) {
		Map<String, Object> response = new HashMap<>();
		response.put(OAuth2ParameterNames.ERROR, error.getErrorCode());
		if (StringUtils.hasText(error.getDescription())) {
			response.put(OAuth2ParameterNames.ERROR_DESCRIPTION, error.getDescription());
		}
		if (StringUtils.hasText(error.getUri())) {
			response.put(OAuth2ParameterNames.ERROR_URI, error.getUri());
		}
		return Collections.unmodifiableMap(response);
	}
}